/*
AES加解密 128bit(16*8bit) (128bit 10轮/192bit 12轮/256bit 14轮)
说明：plaintext[16]:明文     ciphertext[16]:密文
AES解密算法过程:
	准备：初始密钥和 10 个扩展密钥   函数：密钥扩展函数 KeyExpansion()
	一：初始变换
		明文和初始密钥进行异或     函数：轮密钥加   AddRoundKey()
	二：9轮循环
		1.S盒字节代换       函数：SubBytes()     InvSubBytes()
		2.行移位 			函数：ShiftRows()    InvShiftRows()
		3.列混合			函数：MixColumns()   InvMixColumns()
		4.字节乘法			函数：Mul()          XMul()
		5.轮密钥加			函数：AddRoundKey()
	三：最终轮
		1.S盒字节代换
		2.行移位
		3.轮密钥加
AES解密顺序从下往上,可优化
*/
#include<stdio.h>
#include<string.h>
#include"AES128.h"

static unsigned char k[11][16];//扩展秘钥
//AES密钥 十进制{80 152 240 183 166 98 250 165 161 52 126 27 251 90 239 186}
static unsigned char Key[16]={
		0x50,0x98,0xF0,0xB7,
    	0xA6,0x62,0xFA,0xA5,
    	0xA1,0x34,0x7E,0x1B,
    	0xFB,0x5A,0xEF,0xBA
};

//S盒--按行展开为一元数组
static unsigned char S[256] = {
	0x63,0x7C,0x77,0x7B,0xF2,0x6B,0x6F,0xC5,0x30,0x01,0x67,0x2B,0xFE,0xD7,0xAB,0x76,
	0xCA,0x82,0xC9,0x7D,0xFA,0x59,0x47,0xF0,0xAD,0xD4,0xA2,0xAF,0x9C,0xA4,0x72,0xC0,
	0xB7,0xFD,0x93,0x26,0x36,0x3F,0xF7,0xCC,0x34,0xA5,0xE5,0xF1,0x71,0xD8,0x31,0x15,
	0x04,0xC7,0x23,0xC3,0x18,0x96,0x05,0x9A,0x07,0x12,0x80,0xE2,0xEB,0x27,0xB2,0x75,
	0x09,0x83,0x2C,0x1A,0x1B,0x6E,0x5A,0xA0,0x52,0x3B,0xD6,0xB3,0x29,0xE3,0x2F,0x84,
	0x53,0xD1,0x00,0xED,0x20,0xFC,0xB1,0x5B,0x6A,0xCB,0xBE,0x39,0x4A,0x4C,0x58,0xCF,
	0xD0,0xEF,0xAA,0xFB,0x43,0x4D,0x33,0x85,0x45,0xF9,0x02,0x7F,0x50,0x3C,0x9F,0xA8,
	0x51,0xA3,0x40,0x8F,0x92,0x9D,0x38,0xF5,0xBC,0xB6,0xDA,0x21,0x10,0xFF,0xF3,0xD2,
	0xCD,0x0C,0x13,0xEC,0x5F,0x97,0x44,0x17,0xC4,0xA7,0x7E,0x3D,0x64,0x5D,0x19,0x73,
	0x60,0x81,0x4F,0xDC,0x22,0x2A,0x90,0x88,0x46,0xEE,0xB8,0x14,0xDE,0x5E,0x0B,0xDB,
	0xE0,0x32,0x3A,0x0A,0x49,0x06,0x24,0x5C,0xC2,0xD3,0xAC,0x62,0x91,0x95,0xE4,0x79,
	0xE7,0xC8,0x37,0x6D,0x8D,0xD5,0x4E,0xA9,0x6C,0x56,0xF4,0xEA,0x65,0x7A,0xAE,0x08,
	0xBA,0x78,0x25,0x2E,0x1C,0xA6,0xB4,0xC6,0xE8,0xDD,0x74,0x1F,0x4B,0xBD,0x8B,0x8A,
	0x70,0x3E,0xB5,0x66,0x48,0x03,0xF6,0x0E,0x61,0x35,0x57,0xB9,0x86,0xC1,0x1D,0x9E,
	0xE1,0xF8,0x98,0x11,0x69,0xD9,0x8E,0x94,0x9B,0x1E,0x87,0xE9,0xCE,0x55,0x28,0xDF,
	0x8C,0xA1,0x89,0x0D,0xBF,0xE6,0x42,0x68,0x41,0x99,0x2D,0x0F,0xB0,0x54,0xBB,0x16
};
//S盒的逆
static unsigned char IS[256] = {
	0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38,0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb,
	0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87,0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb,
	0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d,0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e,
	0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2,0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25,
	0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16,0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92,
	0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda,0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84,
	0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a,0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06,
	0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02,0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b,
	0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea,0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73,
	0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85,0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e,
	0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89,0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b,
	0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20,0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4,
	0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31,0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f,
	0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d,0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef,
	0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0,0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61,
	0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26,0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d
};

/**
  * @brief  字节乘法(x乘法)
  * @param  n
  * @return x
  * @note   none
  */
static int XMul(int n)
{
	int x;
	x=n<<1;   //左移1位
	if(n&0b10000000){   //判断最高位是0还是1
		x=x^0b00011011;   //如果是1，就进行异或
	}
	return x;  //是0就返回左移后的值
}

/**
  * @brief  字节乘法
  * @param  a
  * @param  b
  * @return a
  * @note   none
  */
static unsigned char Mul(unsigned char a,unsigned char b)
{
	int temp;
	for(temp=a,a=0;b;b=b>>1){ //b每次右移1位
		if(b&1){         //最低位和1比较
			a=a^temp;
		}
		temp=XMul(temp);
	} 
	return a;
}

/**
  * @brief  轮密钥加
  * @param  a
  * @param  Key
  * @return none
  * @note   none
  */
static void AddRoundKey( unsigned char *a , unsigned char *Key ){
	for( int i = 0 ; i < 16 ; i ++ )
		a[i] ^= Key[i] ;
}

/**
  * @brief  S盒字节代换
  * @param  input
  * @return none
  * @note   none
  */
static void SubBytes( unsigned char *input ){
	for( int i = 0 ; i < 16 ; i ++ )
		input[i] = S[input[i]] ;
}

/**
  * @brief  S盒字节代换逆变换
  * @param  input
  * @return none
  * @note   none
  */
static void InvSubBytes( unsigned char *input ){
	for( int i = 0 ; i < 16 ; i ++ )
		input[i] = IS[input[i]] ;
}

/**
  * @brief  行移位—矩阵按列展开
  * @param  a
  * @return none
  * @note   none
  */
static void ShiftRows( unsigned char *a ){
	unsigned char b[16] ;
	b[ 0] = a[ 0] ;	b[ 4] = a[ 4] ;	b[ 8] = a[ 8] ;	b[12] = a[12] ;
	b[ 1] = a[ 5] ;	b[ 5] = a[ 9] ;	b[ 9] = a[13] ;	b[13] = a[ 1] ;
	b[ 2] = a[10] ;	b[ 6] = a[14] ;	b[10] = a[ 2] ;	b[14] = a[ 6] ;
	b[ 3] = a[15] ;	b[ 7] = a[ 3] ;	b[11] = a[ 7] ;	b[15] = a[11] ;
	for( int i = 0 ; i < 16 ; i ++ )
		a[i] = b[i] ;
}

/**
  * @brief  行移位逆变换
  * @param  a
  * @return none
  * @note   none
  */
static void InvShiftRows( unsigned char *a ){
	unsigned char b[16] ;
	b[ 0] = a[ 0] ;	b[ 4] = a[ 4] ;	b[ 8] = a[ 8] ;	b[12] = a[12] ;
	b[ 1] = a[13] ;	b[ 5] = a[ 1] ;	b[ 9] = a[ 5] ;	b[13] = a[ 9] ;
	b[ 2] = a[10] ;	b[ 6] = a[14] ;	b[10] = a[ 2] ;	b[14] = a[ 6] ;
	b[ 3] = a[ 7] ;	b[ 7] = a[11] ;	b[11] = a[15] ;	b[15] = a[ 3] ;
	for( int i = 0 ; i < 16 ; i ++ )
		a[i] = b[i] ;
} 

/**
  * @brief  列混合运算
  * @param  a
  * @return none
  * @note   固定多项式c(x)对应的4字节向量为（03 01 01 02），经过三次循环左移得到（02 03 01 01
  */
static void MixColumns( unsigned char *a ){
	unsigned char b[16] ;
	b[ 0] = Mul(0x02,a[0]) ^ Mul(0x03,a[1]) ^ a[2] ^ a[3];
	b[ 1] = Mul(0x02,a[1]) ^ Mul(0x03,a[2]) ^ a[3] ^ a[0];
	b[ 2] = Mul(0x02,a[2]) ^ Mul(0x03,a[3]) ^ a[0] ^ a[1];
	b[ 3] = Mul(0x02,a[3]) ^ Mul(0x03,a[0]) ^ a[1] ^ a[2];
	b[ 4] = Mul(0x02,a[4]) ^ Mul(0x03,a[5]) ^ a[6] ^ a[7];
	b[ 5] = Mul(0x02,a[5]) ^ Mul(0x03,a[6]) ^ a[7] ^ a[4];
	b[ 6] = Mul(0x02,a[6]) ^ Mul(0x03,a[7]) ^ a[4] ^ a[5];
	b[ 7] = Mul(0x02,a[7]) ^ Mul(0x03,a[4]) ^ a[5] ^ a[6];
	b[ 8] = Mul(0x02,a[8]) ^ Mul(0x03,a[9]) ^ a[10] ^ a[11];
	b[ 9] = Mul(0x02,a[9]) ^ Mul(0x03,a[10]) ^ a[11] ^ a[8];
	b[10] = Mul(0x02,a[10]) ^ Mul(0x03,a[11]) ^ a[8] ^ a[9];
	b[11] = Mul(0x02,a[11]) ^ Mul(0x03,a[8]) ^ a[9] ^ a[10];
	b[12] = Mul(0x02,a[12]) ^ Mul(0x03,a[13]) ^ a[14] ^ a[15];
	b[13] = Mul(0x02,a[13]) ^ Mul(0x03,a[14]) ^ a[15] ^ a[12];
	b[14] = Mul(0x02,a[14]) ^ Mul(0x03,a[15]) ^ a[12] ^ a[13];
	b[15] = Mul(0x02,a[15]) ^ Mul(0x03,a[12]) ^ a[13] ^ a[14];
	for( int i = 0 ; i < 16 ; i ++ )
		a[i] = b[i] ;
}

/**
  * @brief  列混合的逆
  * @param  a
  * @return none
  * @note   c(x)逆多项式对应的4字节向量为(0B 0D 09 0E), 经过三次循环左移得到(0E 0B 0D 09)
  */
static void InvMixColumns(unsigned char *a)
{
	unsigned char b[16];
	b[0] = Mul(0x0E, a[0]) ^ Mul(0x0B, a[1]) ^ Mul(0x0D, a[2]) ^ Mul(0x09, a[3]);
	b[1] = Mul(0x0E, a[1]) ^ Mul(0x0B, a[2]) ^ Mul(0x0D, a[3]) ^ Mul(0x09, a[0]);
	b[2] = Mul(0x0E, a[2]) ^ Mul(0x0B, a[3]) ^ Mul(0x0D, a[0]) ^ Mul(0x09, a[1]);
	b[3] = Mul(0x0E, a[3]) ^ Mul(0x0B, a[0]) ^ Mul(0x0D, a[1]) ^ Mul(0x09, a[2]);
	b[4] = Mul(0x0E, a[4]) ^ Mul(0x0B, a[5]) ^ Mul(0x0D, a[6]) ^ Mul(0x09, a[7]);
	b[5] = Mul(0x0E, a[5]) ^ Mul(0x0B, a[6]) ^ Mul(0x0D, a[7]) ^ Mul(0x09, a[4]);
	b[6] = Mul(0x0E, a[6]) ^ Mul(0x0B, a[7]) ^ Mul(0x0D, a[4]) ^ Mul(0x09, a[5]);
	b[7] = Mul(0x0E, a[7]) ^ Mul(0x0B, a[4]) ^ Mul(0x0D, a[5]) ^ Mul(0x09, a[6]);
	b[8] = Mul(0x0E, a[8]) ^ Mul(0x0B, a[9]) ^ Mul(0x0D, a[10]) ^ Mul(0x09, a[11]);
	b[9] = Mul(0x0E, a[9]) ^ Mul(0x0B, a[10]) ^ Mul(0x0D, a[11]) ^ Mul(0x09, a[8]);
	b[10] = Mul(0x0E, a[10]) ^ Mul(0x0B, a[11]) ^ Mul(0x0D, a[8]) ^ Mul(0x09, a[9]);
	b[11] = Mul(0x0E, a[11]) ^ Mul(0x0B, a[8]) ^ Mul(0x0D, a[9]) ^ Mul(0x09, a[10]);
	b[12] = Mul(0x0E, a[12]) ^ Mul(0x0B, a[13]) ^ Mul(0x0D, a[14]) ^ Mul(0x09, a[15]);
	b[13] = Mul(0x0E, a[13]) ^ Mul(0x0B, a[14]) ^ Mul(0x0D, a[15]) ^ Mul(0x09, a[12]);
	b[14] = Mul(0x0E, a[14]) ^ Mul(0x0B, a[15]) ^ Mul(0x0D, a[12]) ^ Mul(0x09, a[13]);
	b[15] = Mul(0x0E, a[15]) ^ Mul(0x0B, a[12]) ^ Mul(0x0D, a[13]) ^ Mul(0x09, a[14]);
	for (int i = 0; i < 16; i++)
		a[i] = b[i];
}

/*
扩展秘钥矩阵 k[11][16]
	k[i][15]  0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15   //下标
	根据字分组成4x4矩阵： 
	        w0 w1 w2 w3  ··· 
	w[i] :  0  4  8  12        //4x4矩阵下标
			1  5  9  13					 
			2  6  10 14				 
			3  7  11 15	
		注：1字=4字节=32bit，每列为一字；一字相当于一组，进行变换
		    4个字（128位）的初始密钥 Key[16] 需要扩展成11个子密钥，共44个字
对于w[i]:
	i!=4的倍数  w[i]=w[i-4]⊕ w[i-1]
	i==4的倍数  w[i]= w[i-4]⊕ T[i-1]
		T是以w[i]的列进行变换：
			①字循环（左移） ②字节代换（S盒） ③轮常量异或RC
			RC：RC[1]=1;RC[i]=0x02·RC[i-1]  
注：i==4的倍数 即为 w[16]的第一列 对应 k[i][15]的 {0 1 2 3} 
	exp:  
		        | T变换 ↓    | 
		RC      | RC[i] 0 0 0 |      //RC的值 
Key[15]=k[0][15]| 0     1 2 3 |   4 5 6 7   8 9 10 11   12 13 14 15   //数字表示下标 
	k[i-1][15]  | 0     1 2 3 |   4 5 6 7   8 9 10 11   12 13 14 15
				|			  |				            m  n  p  q
	  k[i][15]  | 0     1 2 3 |   4 5 6 7   8 9 10 11   12 13 14 15
                | a     b c d |
  	T变换：
  		if i==0 
	  		上一组进行字循环  n p q m,对应下标{13,14,15,12} -->S盒替换-->^ RC[i]
	  	if i=1或2或3
		  	 上一组进行字循环  n p q m,对应下标{13,14,15,12} -->S盒替换-->^ 0
*/
/**
  * @brief  密钥扩展算法
  * @param  K 扩展秘钥
  * @return none
  * @note   none
  */
static void KeyExpansion(unsigned char K[16],unsigned char k[11][16])
{
    unsigned char RC[10];
	RC[0]=1;
	int i;
	for(i=1;i<10;i++)
		RC[i]=Mul(0x02,RC[i-1]);
	for(i=0;i<16;i++)
		k[0][i]=K[i];
	for(i=1;i<11;i++)
	{
	    k[i][0]=k[i-1][0]^S[k[i-1][13]]^RC[i-1];
		k[i][1]=k[i-1][1]^S[k[i-1][14]];
		k[i][2]=k[i-1][2]^S[k[i-1][15]];
		k[i][3]=k[i-1][3]^S[k[i-1][12]];
		k[i][4]=k[i-1][4]^k[i][0];
		k[i][5]=k[i-1][5]^k[i][1];
		k[i][6]=k[i-1][6]^k[i][2];
		k[i][7]=k[i-1][7]^k[i][3];
		k[i][8]=k[i-1][8]^k[i][4];
		k[i][9]=k[i-1][9]^k[i][5];
		k[i][10]=k[i-1][10]^k[i][6];
		k[i][11]=k[i-1][11]^k[i][7];
		k[i][12]=k[i-1][12]^k[i][8];
		k[i][13]=k[i-1][13]^k[i][9];
		k[i][14]=k[i-1][14]^k[i][10];
		k[i][15]=k[i-1][15]^k[i][11];
	}
}

/**
  * @brief  AES算法加密函数
  * @param  plaintext 明文密码
  * @param  ciphertext 密文密码 传入需memset清0x00
  * @param  k 扩展秘钥
  * @param  Round 加密轮数(128bit 10轮/192bit 12轮/256bit 14轮)
  * @return none
  * @note   none
  */
static void AES(unsigned char plaintext[16], unsigned char ciphertext[16], unsigned char k[11][16],int Round)
{
	int i,round;
	for(i=0;i<16;i++){
		ciphertext[i]=plaintext[i];}
	AddRoundKey(ciphertext,k[0]);
	for(round=1;round<Round;round++){
		SubBytes(ciphertext);
		ShiftRows(ciphertext);
		MixColumns(ciphertext);
		AddRoundKey(ciphertext,k[round]);
	}
	SubBytes(ciphertext);
	ShiftRows(ciphertext);
	AddRoundKey(ciphertext,k[Round]);
}

/**
  * @brief  AES算法解密函数
  * @param  plaintext 明文密码 传入需memset清0x00
  * @param  ciphertext 密文密码
  * @param  k 扩展秘钥
  * @param  Round 加密轮数(128bit 10轮/192bit 12轮/256bit 14轮)
  * @return none
  * @note   none
  */
static void RAES(unsigned char plaintext[16], unsigned char ciphertext[16], unsigned char k[11][16], int Round)
{
	if (1)
	{
		/*AES解密的一般形式*/
		int i,round;
		for(i=0;i<16;i++){
			plaintext[i]=ciphertext[i];}
		AddRoundKey(plaintext,k[Round]);
		InvShiftRows(plaintext);
		InvSubBytes(plaintext);
		for(round=9;round>0;round--){
			AddRoundKey(plaintext,k[round]);
			InvMixColumns(plaintext);
			InvShiftRows(plaintext);
			InvSubBytes(plaintext);
		}
		AddRoundKey(plaintext,k[0]);
	} else {
		/*AES解密的优化，与AES加密是对称结构*/
		/*每轮新的扩展密钥 MRK是 原来扩展密钥 ERK的逆列混合变换；并且使用顺序相反*/
		int i,round;
		for(i=0;i<16;i++){
			plaintext[i]=ciphertext[i];}
		AddRoundKey(ciphertext,k[0]);
		for(round=Round-1;round>0;round--){
			InvSubBytes(plaintext);
			InvShiftRows(plaintext);
			InvMixColumns(plaintext);
			InvMixColumns(k[round]);         //MRK 
			AddRoundKey(plaintext,k[round]);
		}
		InvSubBytes(plaintext);
		InvShiftRows(plaintext);
		AddRoundKey(plaintext,k[0]);
	}
}

/**
  * @brief  AES128加密
  * @param  plaintext  明文
  * @param  ciphertext 密文
  * @return none
  * @note   
	//明文密码 十进制{94 118 173 3 242 233 174 200 117 52 161 142 196 14 93 28}
	unsigned char plaintext[16]={
			0x5E,0x76,0xAD,0x03,
			0xF2,0xE9,0xAE,0xC8,
			0x75,0x34,0xA1,0x8E,
			0xC4,0x0E,0x5D,0x1C
	};
  */
void AES128EnCode(unsigned char plaintext[16], unsigned char ciphertext[16])
{
	int i;

	printf("Plaintext:\n");
	for(i=0;i<16;i++){
	 	printf("%02x ",plaintext[i]);}
	printf("\n");

	//加密
	// memset(ciphertext,0x00,sizeof(ciphertext));
	KeyExpansion(Key,k);	//扩展秘钥
	AES(plaintext,ciphertext,k,10);
	printf("Ciphertext:\n");
	for(i=0;i<16;i++){
	 	printf("%02x ",ciphertext[i]);
	}
	printf("\n");
}

/**
  * @brief  AES128解密
  * @param  ciphertext 密文
  * @param  plaintext  明文
  * @return none
  * @note   
	//密文密码 十进制{94 118 173 3 242 233 174 200 117 52 161 142 196 14 93 28}
	unsigned char ciphertext[16]={
			0x5E,0x76,0xAD,0x03,
			0xF2,0xE9,0xAE,0xC8,
			0x75,0x34,0xA1,0x8E,
			0xC4,0x0E,0x5D,0x1C
	};
  */
void AES128DeCode(unsigned char ciphertext[16], unsigned char plaintext[16])
{
	int i;

	printf("Ciphertext:\n");
	for(i=0;i<16;i++){
	 	printf("%02x ",ciphertext[i]);}
	printf("\n");

	//解密
	// memset(plaintext,0x00,sizeof(plaintext));
	KeyExpansion(Key,k);	//扩展秘钥
	RAES(plaintext,ciphertext,k,10);
	printf("Decode Plaintext:\n");
	for(i=0;i<16;i++){
	 	printf("%02x ",plaintext[i]);
	}
	printf("\n");
}

/**
  * @brief  数组比较
  * @param  arr1 数组1
  * @param  arr2 数组2
  * @param  arr_length 数组长度
  * @return 1 成功 / 0 失败
  * @note   none
  */
int ArrayCompare(unsigned char *arr1, unsigned char * arr2, unsigned int arr_length)
{
	int i = 0;
	for(i = 0; i < arr_length; i++)
	{
		if (arr1[i] != arr2[i])
		{
			printf("arr1 != arr2\n");
			return 0;
		}
		i++;
	}
	printf("arr1 == arr2\n");
	return 1;
}

// int main(void)
// {
// 	int i;
// 	unsigned char ciphertext[16];  //加密密码
// 	//明文密码 十进制{94 118 173 3 242 233 174 200 117 52 161 142 196 14 93 28}
// 	unsigned char plaintext[16]={
// 		0x5E,0x76,0xAD,0x03,
// 		0xF2,0xE9,0xAE,0xC8,
// 		0x75,0x34,0xA1,0x8E,
// 		0xC4,0x0E,0x5D,0x1C
// 	};
// 	//AES密钥 十进制{80 152 240 183 166 98 250 165 161 52 126 27 251 90 239 186}
// 	unsigned char Key[16]={
// 		0x50,0x98,0xF0,0xB7,
// 		0xA6,0x62,0xFA,0xA5,
// 		0xA1,0x34,0x7E,0x1B,
// 		0xFB,0x5A,0xEF,0xBA
// 	};

// 	printf("Plaintext:\n");
// 	for(i=0;i<16;i++){
// 	 	printf("%02x ",plaintext[i]);}
// 	printf("\n");

// 	//加密
// 	memset(ciphertext,0x00,sizeof(ciphertext));
// 	KeyExpansion(Key,k);	//扩展秘钥
// 	AES(plaintext,ciphertext,k,10);
// 	printf("Ciphertext:\n");
// 	for(i=0;i<16;i++){
// 	 	printf("%02x ",ciphertext[i]);
// 	} 
// 	printf("\n");

// 	//解密
// 	memset(plaintext,0x00,sizeof(plaintext));
// 	KeyExpansion(Key,k);	//扩展秘钥
// 	RAES(plaintext,ciphertext,k,10);
// 	printf("Decode Plaintext:\n");
// 	for(i=0;i<16;i++){
// 	 	printf("%02x ",plaintext[i]);
// 	} 
// 	printf("\n");
// 	return 0;
// }

